package org.particles.domain;

import java.util.HashMap;
import java.util.Map;

import org.particles.domain.field.FieldParams;

/**
 * generic particle that have impulse and place properties. 
 */
public class AbstractParticle implements Particle {
	/**
	 * direction and speed of particle.
	 */
	private Vector impulse;
	/**
	 * place (coordinates) where the particle resides in the space.
	 */
	private Vector spacePlace;
	/**
	 * saves information in which fields/forces this particle is embedded in.
	 */
	private long embeddedIntoFields;
	private double radius = 2.5;
	private Map<Long, FieldParams> fieldToStrengthMap = new HashMap<Long, FieldParams>();
	
	/**
	 * @param fields determines into which fields this particle in embedded.
	 */
	public void embedIntoFields(final long fields) {
		this.embeddedIntoFields = fields;
	}
	
	@Override
	public long getFields() {
		return embeddedIntoFields;
	}

	@Override
	public Vector getSpacePlace() {
		return spacePlace;
	}

	@Override
	public void setSpacePlace(Vector spacePlace) {
		this.spacePlace = spacePlace;
	}

	@Override
	public Vector getImpulse() {
		return impulse;
	}

	@Override
	public void setImpulse(Vector impulse) {
		this.impulse = impulse;
	}

	@Override
	public double distanceTo(Particle particle) {
		return particle.getSpacePlace().distanceTo(this.getSpacePlace());
	}

	@Override
	public void copyStateFrom(final Particle particle) {
		this.getImpulse().copyStateFrom(particle.getImpulse());
		this.getSpacePlace().copyStateFrom(particle.getSpacePlace());
	}

	@Override
	public String toString() {
		String str = "[impulse = ";
		if(impulse == null) {
			str += "null";
		}
		else {
			str += impulse.toString();
		}
		str += "; spacePlace = ";
		if(spacePlace == null) {
			str += "null";
		}
		else {
			str += spacePlace.toString();
		}
		str += "]";
		return str;
	}

	@Override
	public double getRadius() {
		return radius;
	}

	@Override
	public void setRadius(final double radius) {
		this.radius = radius;
	}
	
	@Override
	public boolean setFieldParams(final long fieldMarker, final FieldParams params) {
		if(this.fieldToStrengthMap.put(fieldMarker, params) == null) {
			return false;
		}
		else {
			return true;
		}
	}

	@Override
	public FieldParams getFieldParams(long fieldMarker) {
		return fieldToStrengthMap.get(fieldMarker);
	}
	
}
